package yartiss.engine.simulation.scheduling.policies.dp;

import java.util.SortedSet;

import yartiss.engine.simulation.IEnergyProfile;
import yartiss.engine.simulation.ISchedulingPolicy;
import yartiss.engine.simulation.events.EventGenerator;
import yartiss.engine.simulation.scheduling.policies.AbstractMonoProcessorSchedulingPolicy;
import yartiss.engine.simulation.scheduling.policies.tools.DPSlacktimeManager;
import yartiss.engine.simulation.system.ITask;
import yartiss.engine.simulation.system.ITaskSet;
import yartiss.engine.simulation.system.taskset.TaskSetFactory;

public class EDLSchedulingPolicy extends AbstractMonoProcessorSchedulingPolicy {

	private DPSlacktimeManager slacktimeManager;
	
	public EDLSchedulingPolicy(DPSlacktimeManager slacktimeManager){
		this.slacktimeManager = slacktimeManager;
	}
	
	@Override
	public String getPolicyName() {
		return "EDL";
	}

	@Override
	public ITaskSet createTaskSet() {
		return TaskSetFactory.getNewInstance("deadline");
	}

	long t = 17;
	long wakeup = -1;
	long lastDate = 0;
	
	@Override
	public ITask chooseNextTask(ITaskSet taskSet, IEnergyProfile energyProfile,	long date, EventGenerator evGen) {
//		lastDate = date;
//		if(wakeup > 0 && date < wakeup)return null;
//		wakeup = -1;
		
		SortedSet<ITask> activeTasks = taskSet.getActiveTasks(date);
		if(!activeTasks.isEmpty()){
			ITask first = activeTasks.first();
			long st = slacktimeManager.getSlackTime(date, taskSet);
			//System.out.println(date +" : slack time = "+st +"   ?  st2 = "+toto.getSlackTime(date, taskSet));
			if(st>0){
				evGen.generateEvent("check_energy_state",0, activeTasks.first(), date + st, null);
				wakeup = date + st;
				return null;
			}
			long hlcet = energyProfile.howLongCanExecute(first);
			if (hlcet <= 0) {
				evGen.generateEvent("energy_failure",0, activeTasks.first(), date, null);
				return null;
			}
			if (hlcet < activeTasks.first().getRemainingCost())
				evGen.generateEvent("check_energy_state",0, activeTasks.first(), date + hlcet, null);
			return activeTasks.first();
		}
		return  null;
	}
	
	@Override
	public ISchedulingPolicy newInstance() {
		return new EDLSchedulingPolicy(new DPSlacktimeManager());
	}
}
